﻿/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 *
 *  This code is provided on an AS IS basis, with no WARRANTIES,
 *  CONDITIONS or GUARANTEES of any kind.
 **/

using System;
using System.Windows;
using Peter.Common.Services;
using Peter.Common.Utilities;
using Peter.Logic;
using Peter.Logic.Interfaces;

namespace Peter
{
   /// <summary>
   /// Interaction logic for App.xaml
   /// </summary>
   public partial class App : IAppMain
   {
      /// <summary>
      /// Raises the <see cref="E:System.Windows.Application.Startup"/> event.
      /// </summary>
      /// <param name="e">A <see cref="T:System.Windows.StartupEventArgs"/> that contains the event data.</param>
      protected override void OnStartup (StartupEventArgs e)
      {
         AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
         ServiceManager.AddSingleton<IAppMain, App> (this);
         ServiceManager.AddSingleton<IMethodInvoker, MethodInvoker> ();
         HandleSingleInstance (e);
         base.OnStartup (e);
      }

      /// <summary>
      /// Handles the application unhandled exception, showing a MessageBox to display the message and the stacktrace of the exception thrown.
      /// </summary>
      /// <param name="sender">Object responsible who fired the event</param>
      /// <param name="args">Argument(s) related to unhandled exceptions</param>
      void CurrentDomain_UnhandledException (object sender, UnhandledExceptionEventArgs args)
      {
         var ex = (Exception)args.ExceptionObject;
         MessageBox.Show (Current.MainWindow,
          String.Format ("Sorry, an unhandled exception has occurred in Peter.\nhttp:\\\\peter.codeplex.com\nPlease report the following error to the Peter team: {0} \n\n Exception StackTrace: {1}",
             ex.Message, ex.StackTrace), "Unhandled exception occured!", MessageBoxButton.OK, MessageBoxImage.Error);

         if (args.IsTerminating)
         {
            MessageBox.Show (Current.MainWindow, "Sorry. The application is going to exit.",
               "Closing the application..", MessageBoxButton.OK, MessageBoxImage.Error);
         }
      }

      /// <summary>
      /// Occurs when an argument is passed in from another instance of Peter.
      /// </summary>
      /// <param name="sender">NULL</param>
      /// <param name="e">Argument data.</param>
      private static void SingleInstanceParameter (object sender, GenericEventArgs<string> e)
      {
         ArgumentService.Instance.AddArgument (e.Data);
      }

      /// <summary>
      /// Handles the single instance of Peter and manages the arguments received by the application.
      /// </summary>
      /// <param name="e">Startup argument(s)</param>
      private void HandleSingleInstance (StartupEventArgs e)
      {
         if (SingleInstance.IsFirstInstance)
         {
            SingleInstance.ArgumentsReceived += SingleInstanceParameter;
            SingleInstance.ListenForArgumentsFromSuccessiveInstances ();

            ServiceManager.Add<IMessageBoxService, MessageBoxService> ();
            ServiceManager.Add<IOpenFileService, OpenFileService> ();
            ServiceManager.Add<ISaveFileService, SaveFileService> ();
            ServiceManager.Add<ITimerService, TimerService> ();

            if (e.Args.Length > 0)
            {
               foreach (var arg in e.Args)
               {
                  ArgumentService.Instance.AddArgument (arg);
               }
            }
         }
         else
         {
            // if there are arguments available, fire it
            if (e.Args.Length > 0)
            {
               foreach (var arg in e.Args)
               {
                  SingleInstance.PassArgumentsToFirstInstance (arg);
               }
            }
            else
            {
               SingleInstance.PassArgumentsToFirstInstance ();
            }

            Environment.Exit (0);
         }
      }
   }
}
